import Koa, { Context } from 'koa'
import KoaBody from 'koa-body'
import Cors from 'koa2-cors'
import { join } from 'path'
import testController from 'controller/TestController'

import { loggerFactory } from '@/util/Log4jsUtil'
import AddressIP from 'ip'
import Session from 'koa-session'
import staticFiles from 'koa-static'
import { errorHandler } from '@/middlewares/ErrorHandler'
import sequelize from '@/util/SystemDatabaseInit'
import { createAllTable } from '@/util/SqliteDbUtil'
import swaggerRouter from '@/swagger'
import { koaSwagger } from '@ykmmky/koa2-swagger-ui'
import { mkdirAsync } from '@/util/FileUtil'

createAllTable(sequelize)

const logger = loggerFactory('app')
const app = new Koa()

// swagger-ui配置
const enableSwagger = true
app.use(
  koaSwagger({
    routePrefix: '/swagger',
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    swaggerUICssRef:
      'https://cdn.bootcdn.net/ajax/libs/swagger-ui/4.10.3/swagger-ui.min.css',
    swaggerUIBundleRef:
      'https://cdn.bootcdn.net/ajax/libs/swagger-ui/4.10.3/swagger-ui-bundle.js',
    swaggerUIPresetRef:
      'https://cdn.bootcdn.net/ajax/libs/swagger-ui/4.10.3/swagger-ui-standalone-preset.js',
    swaggerOptions: {
      // url: 'http://petstore.swagger.io/v2/swagger.json',
      url: '/swagger.json',
    },
  })
)

const CONFIG = {
  key: 'sessionId',
  maxAge: 86400000,
  autoCommit: true,
  overwrite: true,
  httpOnly: true,
  signed: true,
  rolling: false,
  renew: false,
}

app.use(Session(CONFIG, app))

// 文件上传配置
// 指定文件上传目录(该目录必须事先存在，否则文件上传时会报错)
const uploadDir = join(__dirname, '../upload')
// 如果文件夹不存在则创建
mkdirAsync(__dirname, '../upload')
app.use(staticFiles(uploadDir))
logger.debug(`文件上传路径: ${uploadDir}`)
app.use(
  KoaBody({
    // 支持文件格式
    multipart: true,
    formidable: {
      // 上传目录
      uploadDir: uploadDir,
      // 保留文件扩展名
      keepExtensions: true,
      // 设置上传文件大小最大限制，默认2M
      maxFileSize: 200 * 1024 * 1024,
    },
  })
)

// 跨域配置
app.use(
  Cors({
    origin: function (ctx: Context) {
      return '*'
    },
    exposeHeaders: ['Authorization'],
    maxAge: 5 * 24 * 60 * 60,
    credentials: true,
    allowMethods: ['GET', 'POST', 'OPTIONS', 'DELETE', 'PUT'],
    allowHeaders: [
      'Content-Type',
      'Authorization',
      'Accept',
      'X-Requested-With',
    ],
  })
)

// 统一异常处理一定要放在所有路由配置之前
app.use(errorHandler)

// 路由配置
app.use(testController.routes()).use(testController.allowedMethods())

// swagger路由用于生成swagger文档
app.use(swaggerRouter.routes()).use(swaggerRouter.allowedMethods())

const port = 3000
const server = app.listen(port, () => {
  logger.info(
    `\n
    koa服务启动:
    http://${AddressIP.address()}:${port}
    http://127.0.0.1:${port}
    `
  )
  if (enableSwagger) {
    logger.info(
      `\n
      swagger地址:
      http://${AddressIP.address()}:${port}/swagger
      http://127.0.0.1:${port}/swagger
      `
    )
  }
})
